package sve;

import graph.Graph;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;

import sve.generator.BoolDecVar;
import sve.generator.Generator;
import sve.generator.RoboticsGen;
import sve.generator.TrackingGen;
import sve.generator.VOIGen;

import com.sun.org.apache.bcel.internal.generic.LoadClass;

import cmdp.HierarchicalParser;
import dk.ange.octave.OctaveEngine;
import dk.ange.octave.OctaveEngineFactory;
import xadd.XADD;
import xadd.XADD.BoolDec;
import xadd.XADD.Expr;

public class Driver {

	public static void main(String[] args) {

		if (args.length > 0) {
			try {
				SVE s = new SVE();
				s.load(CommandParser.parse(args, "-f", 0));
				String q = CommandParser.parse(args, "-q", 1);
				String e = CommandParser.parse(args, "-e", 2);
				s.solveP(q.split(","), e.split(","));
			} catch (Exception ex) {
				ex.printStackTrace();
				System.out.println("\n-f: File path\n-q: Query\n-e: Evidence");
			}
		} else {
			final String dataPath = "./src/sve/";
			timeSpaceTest(dataPath);
			// testTracker(dataPath, new StringBuilder(), "x" + (1 + 1), Integer.toString(1 + 1));
			// testRobotics(dataPath, new StringBuilder(), "x" + (2 + 1), Integer.toString(2 + 1));
			// showGraph();
		}
		// Generator.generateDBN();
	}

	private static void showGraph() {
		XADD x = new XADD();
		// x.getVarIndex(x.new BoolDec("b2"), true);
		// int id = x.buildCanonicalXADD((ArrayList) ((ArrayList) HierarchicalParser
		// .ParseFile("./mat-script/tracker_b2o1")).get(0));
		int id = x.buildCanonicalXADD((ArrayList) ((ArrayList) HierarchicalParser.ParseFile("./src/sve/Robotics.sve"))
				.get(0));
		x.getGraph(id).launchViewer();
	}

	private static void timeSpaceTest(String dataPath) {
		StringBuilder time = new StringBuilder();
		StringBuilder space = new StringBuilder();
		String robotInput = "";
		for (int i = 0; i < 10; i++) {
			robotInput = robotInput + (i == 0 ? "" : ",") + "x" + (i + 1) + "";

			// long ts = System.currentTimeMillis();
			space.append(testRobotics(dataPath, time, robotInput) + "\n");
			// time.append((System.currentTimeMillis() - ts) + ", ");
			// ts = System.currentTimeMillis();
			// testVOI(dataPath);
		//	space.append(testTracker(dataPath, time, "x" + (i + 1), Integer.toString(i + 1)) + "\n");
			// time.append((System.currentTimeMillis() - ts) + "\n");

			Utils.print("./mat-script/time_r.csv", time.toString());
			System.out.println(time.toString());
			Utils.print("./mat-script/space_r.csv", space.toString());
			System.out.println(time.toString());
		}
	}

	private static int testTracker(String dataPath, StringBuilder time, String... input) {
		final String evidence = "o1";
		final String query = input[0];// "x2";
		input[0] = input[0].replace(",", "").replace("=", "");
		final String inputName = "Tracking";
		String[][] ss = CommandParser.parseAssignments(""); // x1=5,x2=8,x3=3
		TrackingGen.generate(dataPath + inputName, Integer.parseInt(input[1])); // ss.length

		long ts = System.currentTimeMillis();
		SVE s = new SVE();
		s.load(dataPath + inputName);
		Pair<Integer, XADD> p = s
				.solveP(query.split(","), evidence.split(","), ss[0], Converter.toDouble(ss[1]), false);
		// p.getValue().getGraph(p.getKey()).launchViewer();
		int space = p.getValue().getBranchCount(p.getKey());
		time.append((System.currentTimeMillis() - ts) + "\n");

		// Pair<double[][], double[][]> temp = Evaluator.generateEvaluationDouble(p,
		// new Evaluator.Range(query, 0, .5, 10), new Evaluator.Range(evidence, 0, .5, 10));

		// String str = Converter.toString(temp.getKey(), ",", "\n");
		// Utils.print("./mat-script/tracker_joint_xy_" + input[0] + ".csv", str);
		// str = Converter.toString(temp.getValue(), ",", "\n");
		// Utils.print("./mat-script/tracker_joint_z_" + input[0] + ".csv", str);

		// str = Converter.toString(
		// Evaluator.generateEvaluationDouble(s.integral(p.getKey(), query), evidence, 0, .5, 10), ",", "\n");
		// Utils.print("./mat-script/tracker_px_" + input[0] + ".csv", str);
		// System.out.println(str);

		return space;
	}

	private static int testRobotics(String dataPath, StringBuilder time, String... input) {
		SVE s = new SVE();
		final String evidence = input[0]; // "x1 = 5"; // , x2 = 8, x3 = 3
		final String inputName = "Robotics";
		input[0] = input[0].replace(",", "").replace("=", "");

		String[][] ss = CommandParser.parseAssignments(evidence); // x1=5,x2=8,x3=3
		RoboticsGen.generate(ss[0].length);

		s.load(dataPath + inputName);
		// String[][] ss = CommandParser.parseAssignments("d=6"); // ,x2=.5
		// String str = Converter.toString(

		// Utils.print("./mat-script/x.csv", Converter.toString(
		// s.generateEvaluationDouble("x1", "x1", ss[0], Converter.toDouble(ss[1]), 0, .1, 10), ",", "\n"));
		// System.exit(1);

		// s.drawGraph(null, "d", "x1");

		// s.evaulateProbIntegrity("x1", "x1", ss[0], Converter.toDouble(ss[1]));

		long ts = System.currentTimeMillis();
		Pair<Integer, XADD> p = s.solveP("d".split(","), evidence.split(","), ss[0], Converter.toDouble(ss[1]), false); // "".split(",");
		Utils.print("mat-script/p" + input[0] + ".txt", "p", p);
		int space = p.getValue().getBranchCount(p.getKey());

		// s.drawGraph(p);
		String str = Converter.toString(Evaluator.generateEvaluationDouble(p, "d", 0, .1, 10), ",", "\n");
		Utils.print("./mat-script/robot" + input[0] + ".csv", str);

		p = s.EP("d", p);
		Utils.print("mat-script/ep" + input[0] + ".txt", "EP", p);
		time.append((System.currentTimeMillis() - ts) + "\n"); // ,

		// p.getValue().getGraph(p.getKey()).launchViewer();

		// System.out.println(str);

		// s.solveP("u".split(","), "".split(","));

		// s.load("./src/sve/VOI");
		// s.solveP("u".split(","), "".split(","));

		return space;
	}

	private static void testVOI(String dataPath) {
		final String evidence = "";
		final String inputName = "VOI";

		String[][] ss = CommandParser.parseAssignments(evidence); // x1=5,x2=8,x3=3
		VOIGen.generate(dataPath + inputName, ss.length);
		SVE s = new SVE();
		s.load(dataPath + inputName);
		Pair<Integer, XADD> p = s.solveP("u".split(","), "".split(","), ss[0], Converter.toDouble(ss[1]), false);
		s.EP("u", p);
		Utils.print("mat-script/ep.txt", "EP", p);
		String str = Converter.toString(Evaluator.generateEvaluationDouble(p, "d", -10, .1, 10), ",", "\n");
		Utils.print("./mat-script/voi.csv", str);
	}

}
